home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / metkit / finddlg.cpp < prev    next >
C/C++ Source or Header  |  1997-06-07  |  7KB  |  220 lines

  1. //    Copyright (C) 1996, 1997 Meta Four Software.  All rights reserved.
  2. //
  3. //  Find dialog sample code
  4. //
  5. //! rev="$Id: finddlg.cpp,v 1.4 1997/05/27 00:06:09 jcw Rel $"
  6.  
  7. #include "stdafx.h"
  8. #include "catfish.h"
  9. #include "scandisk.h"
  10.  
  11. #ifdef _DEBUG
  12. #undef THIS_FILE
  13. static char BASED_CODE THIS_FILE[] = __FILE__;
  14. #endif
  15.  
  16. /////////////////////////////////////////////////////////////////////////////
  17. // CMyEdit subclassed control
  18.  
  19. BEGIN_MESSAGE_MAP(CMyEdit, CEdit)
  20.     //{{AFX_MSG_MAP(CMyEdit)
  21.     ON_WM_CHAR()
  22.     //}}AFX_MSG_MAP
  23. END_MESSAGE_MAP()
  24.  
  25. void CMyEdit::OnChar(UINT ch_, UINT rep_, UINT flags_)
  26. {
  27.         // only accept the characters which are allowed in a DOS filename
  28.     bool accept = ('A' <= ch_ && ch_ <= 'Z') ||
  29.                   ('a' <= ch_ && ch_ <= 'z') ||
  30.                   ('0' <= ch_ && ch_ <= '9') ||
  31.                   strchr("$%'+-@{}~`!#()&_", ch_) != 0;
  32.                   
  33.     if (accept || ch_ == VK_BACK || (acceptDot && strchr(".?* ", ch_)))
  34.         CEdit::OnChar(ch_, rep_, flags_) ;
  35.     else
  36.         MessageBeep(0);
  37. }
  38.  
  39. /////////////////////////////////////////////////////////////////////////////
  40. // CFindDialog dialog
  41.  
  42. CFindDialog::CFindDialog(CWnd* pParent /*=NULL*/)
  43.     : CDialog(CFindDialog::IDD, pParent), m_nameEditCtrl (true)
  44. {
  45.     //{{AFX_DATA_INIT(CFindDialog)
  46.     m_maxDate = "";
  47.     m_minDate = "";
  48.     m_nameEdit = "";
  49.     m_singleCat = FALSE;
  50.     m_minSize = "";
  51.     m_maxSize = "";
  52.     //}}AFX_DATA_INIT
  53.  
  54.     FixCriteria(); 
  55. }
  56.  
  57. void CFindDialog::DoDataExchange(CDataExchange* pDX)
  58. {
  59.     CDialog::DoDataExchange(pDX);
  60.     //{{AFX_DATA_MAP(CFindDialog)
  61.     DDX_Text(pDX, IDC_MAX_DATE, m_maxDate);
  62.     DDV_MaxChars(pDX, m_maxDate, 6);
  63.     DDX_Text(pDX, IDC_MIN_DATE, m_minDate);
  64.     DDV_MaxChars(pDX, m_minDate, 6);
  65.     DDX_Text(pDX, IDC_NAME_EDIT, m_nameEdit);
  66.     DDV_MaxChars(pDX, m_nameEdit, 15);
  67.     DDX_Check(pDX, IDC_SINGLE_CAT, m_singleCat);
  68.     DDX_Text(pDX, IDC_MIN_SIZE, m_minSize);
  69.     DDV_MaxChars(pDX, m_minSize, 6);
  70.     DDX_Text(pDX, IDC_MAX_SIZE, m_maxSize);
  71.     DDV_MaxChars(pDX, m_maxSize, 6);
  72.     //}}AFX_DATA_MAP
  73. }
  74.  
  75. BEGIN_MESSAGE_MAP(CFindDialog, CDialog)
  76.     //{{AFX_MSG_MAP(CFindDialog)
  77.     //}}AFX_MSG_MAP
  78. END_MESSAGE_MAP()
  79.  
  80.  
  81. /////////////////////////////////////////////////////////////////////////////
  82. // CFindDialog message handlers
  83.  
  84. BOOL CFindDialog::OnInitDialog()
  85. {
  86.     CenterWindow();
  87.     CDialog::OnInitDialog();
  88.     
  89.     m_nameEditCtrl.SubclassDlgItem(IDC_NAME_EDIT, this);
  90.     
  91.     CWnd* wnd = GetDlgItem(IDC_SINGLE_CAT);
  92.     ASSERT(wnd);
  93.     
  94.     wnd->SetWindowText("&Only search in '" + m_currCatName + "'");
  95.     
  96.     FixCriteria(); 
  97.     return TRUE;  // return TRUE  unless you set the focus to a control
  98. }
  99.  
  100. bool CFindDialog::Execute(const char* name)
  101. {
  102.     m_currCatName = name;
  103.     
  104.     if (DoModal() != IDOK)
  105.         return false;
  106.         
  107.     FixCriteria();
  108.     return true;    
  109. }
  110.  
  111.     static int ConvDate(const CString& s_, WORD default_ =0)
  112.     {
  113.         if (s_.GetLength() == 6)
  114.         {
  115.             int y = atoi(s_.Left(2)) - 80;
  116.             int m = atoi(s_.Mid(2, 2));
  117.             int d = atoi(s_.Right(2));
  118.             
  119.             if (y < -40)    // accepts 1940 .. 2039
  120.                 y += 100;
  121.                 
  122.             if (1 <= m && m <= 12 && 1 <= d && d <= 31)
  123.                 return (y << 9) | (m << 5) | d;
  124.         }
  125.         
  126.         return default_;
  127.     }
  128.     
  129. void CFindDialog::FixCriteria()
  130. {
  131.     m_upName = m_nameEdit;
  132.     m_upName.MakeUpper(); 
  133.      
  134.         // if there are no wildcards, then add them at both ends (unanchored)
  135.     if (m_upName.SpanExcluding("?*") == m_upName)
  136.         m_upName = "*" + m_upName + "*";
  137.         
  138.     m_loDate = ConvDate(m_minDate);
  139.     m_hiDate = ConvDate(m_maxDate, 0x7FFF);
  140.     
  141.     m_loSize = atol(m_minSize) * 1000;
  142.     m_hiSize = m_maxSize.IsEmpty() ? 0x7FFFFFFFL
  143.                                    : atol(m_maxSize) * 1000 + 999;
  144.  
  145.         // by avoiding all unnecessary access we also avoid on-demand loading
  146.     m_checkName = !m_nameEdit.IsEmpty();
  147.     m_checkDate = !m_minDate.IsEmpty() || !m_maxDate.IsEmpty();
  148.     m_checkSize = !m_minSize.IsEmpty() || !m_maxSize.IsEmpty();
  149. }
  150.  
  151. bool CFindDialog::NeedsCompare() const
  152. {
  153.     return m_checkName || m_checkDate || m_checkSize;
  154. }
  155.  
  156.         // a very simple wildcard matching routine, does just '*' and '?'
  157.     static bool fWildMatch(const char* crit, const char* val)
  158.     {
  159.         for (;;)
  160.         {                
  161.             switch (*crit)
  162.             {                          
  163.                 default:    if (*crit != *val)  // if different chars
  164.                                 return false;
  165.                             if (!*crit)         // if equal and both null
  166.                                 return true;
  167.                             // else fall through
  168.                             
  169.                 case '?':   if (!*val)          // if at end
  170.                                 return false;
  171.  
  172.                             ++crit;
  173.                             ++val;
  174.                             break;              // ok, both advanced one
  175.  
  176.                 case '*':   ++crit;
  177.                             
  178.                             for (;;)
  179.                                 if (fWildMatch(crit, val))  // if rest matches
  180.                                     return true;
  181.                                 else if (!*val)             // if nothing left
  182.                                     return false;   
  183.                                 else
  184.                                     ++val;      // try again one char further
  185.             }
  186.         }
  187.     }
  188.     
  189. bool CFindDialog::Match(const c4_RowRef& row_) const
  190. {
  191.     if (m_checkName)
  192.     {
  193.         CString s = pName (row_);
  194.         s.MakeUpper(); // compare in uppercase to avoid case sensitivity
  195.         
  196. //      if (s.Find(m_upName) < 0)
  197.         if (!fWildMatch(m_upName, s))
  198.             return false;
  199.     }
  200.                         
  201.     if (m_checkDate)
  202.     {
  203.         int v = (int) pDate (row_);
  204.         if (v < m_loDate || v > m_hiDate)
  205.             return false;
  206.     }
  207.                         
  208.     if (m_checkSize)
  209.     {
  210.         long v = pSize (row_);
  211.         if (v < m_loSize || v > m_hiSize)
  212.             return false;
  213.     } 
  214.     
  215.     return true;
  216. }
  217.  
  218. /////////////////////////////////////////////////////////////////////////////
  219. // $Id: finddlg.cpp,v 1.4 1997/05/27 00:06:09 jcw Rel $
  220.